from waveapi import events, robot, appengine_robot_runner
from waveapi.document import Range

from settings import LINKS, DEFAULT

import re

INTRO_TEXT = """
Linky-bot has been added!
Use [[site:arg1:arg2:... query | text]] to add a link.

For example:
	[[wiki:en Python_(Programming_Language) | python]]
"""


LINK_RE = re.compile(r'\[\[(?:(?P<func>\w*)(?P<args>(?:\:\w*)*)\s+)?(?P<query>[^|\]:]+)(?:\|\s*(?P<text>[^\]]+))?\s*\]\]')

VALID = "#3355FF"
INVALID = "#CC1100"
NONLINK = "#666666"

class Link(object):
	def __init__(self, match):
		self.func = (match.group('func') or str(DEFAULT)).strip()
		self.args = (match.group('args') or ':')[1:].strip().split(':')
		self.query = match.group('query').strip()
		self.text = (match.group('text') or self.query).strip()

		self.start = match.start()
		self.end = match.end()
		


def OnBlipSubmitted(event, wavelet):

	matches = list(LINK_RE.finditer(event.blip.text))
	matches.reverse()

	if matches:
		event.blip.append(" ")

	for match in matches:
		link = Link(match)

		matchrange = event.blip.range(link.start, link.end)
		annots = {"style/textDecoration": "none", "style/color": NONLINK}

		if link.func in LINKS:
			url = LINKS[link.func].get_link(link.query,*link.args)
			annots["link/manual"] = url
			
			isvalid = LINKS[link.func].get_isvalid(link.query,*link.args)

			annots["style/color"] = VALID if isvalid else INVALID

		matchrange.replace(link.title, annots)

def OnDocumentChanged(event, wavelet):
	
	matches = list(LINK_RE.finditer(event.blip.text))
	matches.reverse()
	
	for match in matches:

		link = Link(match)

		matchrange = event.blip.range(link.start+2, link.end-2)
		if link.func in LINKS:
			isvalid = LINKS[link.func].get_isvalid(link.query,*link.args)
			matchrange.annotate("style/color", VALID if isvalid else INVALID)
		else:
			matchrange.annotate("style/color", NONLINK)
		

def OnRobotAdded(event, wavelet):
	wavelet.reply(INTRO_TEXT)


if __name__ == '__main__':
	linky = robot.Robot('linky-bot',
			image_url='http://linky-bot.appspot.com/assets/icon.png',
			version='0.7.0',
			profile_url='http://linky-bot.appspot.com/')
	
	#register handlers...
	linky.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded)
	linky.RegisterHandler(events.BLIP_SUBMITTED, OnBlipSubmitted)
	linky.RegisterHandler(events.DOCUMENT_CHANGED, OnDocumentChanged)	
	appengine_robot_runner.run(linky)

